package org.bt.common.utils;

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;

/**
 * @author zwj
 * @date 2022/12/8
 * @description TODO rsa加解密
 */

public class RsaUtil {


    /**
     * Base64编码
     */
    private static final java.util.Base64.Encoder ENCODER = java.util.Base64.getEncoder();

    /**
     * Base64解码
     */
    private static final java.util.Base64.Decoder DECODER = java.util.Base64.getDecoder();

    /**
     * RSA私钥解密
     *
     * @param str 加密字符串
     * @param key 私钥
     *
     * @return 铭文
     */
    public static String decrypt(String str, String key) {
        StringBuffer stringBuffer = new StringBuffer();
        try {
            // 过滤掉\r\n
            key = key.replace("\r\n", "");
            key = key.replace(" ", "");
            // 取得私钥
            PKCS8EncodedKeySpec x509KeySpec = new PKCS8EncodedKeySpec(DECODER.decode(key));
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(x509KeySpec);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            // 该密钥能够加密的最大字节长度
            int splitLength = ((RSAPrivateKey) privateKey).getModulus().bitLength() / 8;
            byte[][] arrays = splitBytes(DECODER.decode(str), splitLength);
            for (byte[] array : arrays) {
                stringBuffer.append(new String(cipher.doFinal(array)));
            }
            return stringBuffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 根据限定的每组字节长度，将字节数组分组
     */
    private static byte[][] splitBytes(byte[] bytes, int splitLength) {

        // bytes与splitLength的余数
        int remainder = bytes.length % splitLength;
        // 数据拆分后的组数，余数不为0时加1
        int quotient = remainder != 0 ? bytes.length / splitLength + 1 : bytes.length / splitLength;
        byte[][] arrays = new byte[quotient][];
        byte[] array = null;
        for (int i = 0; i < quotient; i++) {
            // 如果是最后一组（quotient-1）,同时余数不等于0，就将最后一组设置为remainder的长度
            if (i == quotient - 1 && remainder != 0) {
                array = new byte[remainder];
                System.arraycopy(bytes, i * splitLength, array, 0, remainder);
            } else {
                array = new byte[splitLength];
                System.arraycopy(bytes, i * splitLength, array, 0, splitLength);
            }
            arrays[i] = array;
        }
        return arrays;
    }
}
